package com.functest.jpwise.deprecated;

import com.functest.jpwise.core.ParameterValue;

import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

/**
 * Represents a factory that creates parameter combinations for a jUnit test in
 * a single-wise manner. Using such a factory ensures that all possible values
 * of each parameter get tested and that this is done with the least possible
 * number of test cases. This is most useful when a tiny number of extremely
 * effective test-cases is desired, such as in a smoke-test suite.
 * 
 * @author Jeremy Reeder
 * @version 2011-11-15
 * @since 2011-10-27
 */
public class AllValuesParameterFactory extends ParameterFactory {
	private Set<ParameterValue> largestSetInList(List<Set<ParameterValue>> list) {
		Set<ParameterValue> largestSet = new HashSet<>();
		for (Set<ParameterValue> set : list)
			if (set.size() > largestSet.size())
				largestSet = set;
		return largestSet;
	}

	protected List<ParameterValue[]> createListOfParameterIdCombinations() {
		final List<ParameterValue[]> listOfParameterIdArrays = new ArrayList<>();
		final int parameterCount = orderedListOfParameterIdSets.size();
		final int testCaseCount = largestSetInList(orderedListOfParameterIdSets)
				.size();
		ParameterValue[][] parameterIds = new ParameterValue[testCaseCount][parameterCount];


        for (int i = 0; i < testCaseCount; i++) {
			for (int j = 0; j < parameterCount; j++) {
				final ParameterValue[] inputIds = orderedListOfParameterIdSets.get(j)
						.toArray(new ParameterValue[0]);

				// each time we repeat a parameter's values, increment the
				// starting point
				// (to minimize the amount of repetition in test-cases once some
				// of the value sets are exhausted)
				final int cycleOffset = i / inputIds.length;

				// start parameter0 at value0, p1 at v1, etc.
				// (to minimize the chance of two similar value sets being
				// tested with uninteresting combinations)
				final int parameterStagger = j;

				parameterIds[i][j] = inputIds[(parameterStagger + cycleOffset + i)
						% inputIds.length];
			}
			listOfParameterIdArrays.add(parameterIds[i]);
		}
		return listOfParameterIdArrays;
	}
}
